package com.kelai.utils;

import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.Map;

/**
 * 时间工具类
 */
@Slf4j
public class DateUtils {

    public static final String MONDAY= "MONDAY";
    public static final String TUESDAY= "TUESDAY";
    public static final String WEDNESDAY= "WEDNESDAY";
    public static final String THURSDAY= "THURSDAY";
    public static final String FRIDAY= "FRIDAY";
    public static final String SATURDAY= "SATURDAY";
    public static final String SUNDAY= "SUNDAY";

    public static final String FIRST_DAY_OF_MONTH= "FIRST_DAY_OF_MONTH";
    public static final String LAST_DAY_OF_MONTH= "LAST_DAY_OF_MONTH";

    public static final String FIRST_WEEK_START = "FIRST_WEEK_START";
    public static final String FIRST_WEEK_END = "FIRST_WEEK_END";
    public static final String SECOND_WEEK_START = "SECOND_WEEK_START";
    public static final String SECOND_WEEK_END = "SECOND_WEEK_END";
    public static final String THIRD_WEEK_START = "THIRD_WEEK_START";
    public static final String THIRD_WEEK_END = "THIRD_WEEK_END";
    public static final String FOURTH_WEEK_START = "FOURTH_WEEK_START";
    public static final String FOURTH_WEEK_END = "FOURTH_WEEK_END";
    public static final String FIFTH_WEEK_START = "FIFTH_WEEK_START";
    public static final String FIFTH_WEEK_END = "FIFTH_WEEK_END";

    public static final String DAY_START_TIME = " 00:00:00";
    public static final String DAY_END_TIME = " 23:59:59";

    /**
     * 根据日期计算本周的开始和结束（周一~周日）
     */
    public static Map<String, LocalDate> getWeekByDate(String date){
        LocalDate current = LocalDate.parse(date);

        LocalDate MONDAY = current.with(DayOfWeek.MONDAY);
        LocalDate TUESDAY = current.with(DayOfWeek.TUESDAY);
        LocalDate WEDNESDAY = current.with(DayOfWeek.WEDNESDAY);
        LocalDate THURSDAY = current.with(DayOfWeek.THURSDAY);
        LocalDate FRIDAY = current.with(DayOfWeek.FRIDAY);
        LocalDate SATURDAY = current.with(DayOfWeek.SATURDAY);
        LocalDate SUNDAY = current.with(DayOfWeek.SUNDAY);

        Map<String, LocalDate> result = Maps.newConcurrentMap();
        result.put("MONDAY", MONDAY);
        result.put("TUESDAY", TUESDAY);
        result.put("WEDNESDAY", WEDNESDAY);
        result.put("THURSDAY", THURSDAY);
        result.put("FRIDAY", FRIDAY);
        result.put("SATURDAY", SATURDAY);
        result.put("SUNDAY", SUNDAY);

        log.info(result.toString());
        return result;

    }

    /**
     * 根据日期计算本月的开始和结束
     */
    public static Map<String, LocalDate> getMonthByDate(String date){
        LocalDate current = LocalDate.parse(date);

//        LocalDate firstDayOfMonth = current.with(TemporalAdjusters.firstDayOfMonth());
//        LocalDate lastDayOfMonth = current.with(TemporalAdjusters.lastDayOfMonth());
        LocalDate firstDayOfMonth = current.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));
        LocalDate fifthWeekStart = current.with(TemporalAdjusters.dayOfWeekInMonth(5, DayOfWeek.MONDAY));
        Map<String, LocalDate> result = Maps.newConcurrentMap();
        if(fifthWeekStart.getMonthValue() == current.getMonthValue()){
            LocalDate lastDayOfMonth = fifthWeekStart.plusDays(6);
            result.put("LAST_DAY_OF_MONTH", lastDayOfMonth);
        }else {
            LocalDate fourthWeekStart = current.with(TemporalAdjusters.dayOfWeekInMonth(4, DayOfWeek.MONDAY));
            LocalDate lastDayOfMonth = fourthWeekStart.plusDays(6);
            result.put("LAST_DAY_OF_MONTH", lastDayOfMonth);
        }

        result.put("FIRST_DAY_OF_MONTH", firstDayOfMonth);

        return result;

    }

    /**
     * 根据日期计算历史6个月，每个月的开始和结束
     */
    public static Map<String, LocalDate> getHistoryByDate(String date){

        LocalDate current = LocalDate.parse(date);

        LocalDate history1= current.minusMonths(1);
        Map<String, LocalDate> history1Data = getMonthByDate(history1.format(DateTimeFormatter.ISO_LOCAL_DATE));
        LocalDate history2= current.minusMonths(2);
        Map<String, LocalDate> history2Data = getMonthByDate(history2.format(DateTimeFormatter.ISO_LOCAL_DATE));
        LocalDate history3= current.minusMonths(3);
        Map<String, LocalDate> history3Data = getMonthByDate(history3.format(DateTimeFormatter.ISO_LOCAL_DATE));
        LocalDate history4= current.minusMonths(4);
        Map<String, LocalDate> history4Data = getMonthByDate(history4.format(DateTimeFormatter.ISO_LOCAL_DATE));
        LocalDate history5= current.minusMonths(5);
        Map<String, LocalDate> history5Data = getMonthByDate(history5.format(DateTimeFormatter.ISO_LOCAL_DATE));
        LocalDate history6= current.minusMonths(6);
        Map<String, LocalDate> history6Data = getMonthByDate(history6.format(DateTimeFormatter.ISO_LOCAL_DATE));

        Map<String, LocalDate> result = Maps.newConcurrentMap();
        result.put("history1Start", history1Data.get(DateUtils.FIRST_DAY_OF_MONTH));
        result.put("history1End", history1Data.get(DateUtils.LAST_DAY_OF_MONTH));
        result.put("history2Start", history2Data.get(DateUtils.FIRST_DAY_OF_MONTH));
        result.put("history2End", history2Data.get(DateUtils.LAST_DAY_OF_MONTH));
        result.put("history3Start", history3Data.get(DateUtils.FIRST_DAY_OF_MONTH));
        result.put("history3End", history3Data.get(DateUtils.LAST_DAY_OF_MONTH));
        result.put("history4Start", history4Data.get(DateUtils.FIRST_DAY_OF_MONTH));
        result.put("history4End", history4Data.get(DateUtils.LAST_DAY_OF_MONTH));
        result.put("history5Start", history5Data.get(DateUtils.FIRST_DAY_OF_MONTH));
        result.put("history5End", history5Data.get(DateUtils.LAST_DAY_OF_MONTH));
        result.put("history6Start", history6Data.get(DateUtils.FIRST_DAY_OF_MONTH));
        result.put("history6End", history6Data.get(DateUtils.LAST_DAY_OF_MONTH));
        System.out.println(result);

        return result;

    }

    /**
     * 根据某个月算第几周的开始和结束
     */
    public static Map<String, LocalDate> getWeekByMonth(String month){
        LocalDate current = LocalDate.parse(month);

        LocalDate firstWeekStart = current.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));
        LocalDate firstWeekEnd = firstWeekStart.plusDays(6);
        LocalDate secondWeekStart = current.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));
        LocalDate secondWeekEnd = secondWeekStart.plusDays(6);
        LocalDate thirdWeekStart = current.with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.MONDAY));
        LocalDate thirdWeekEnd = thirdWeekStart.plusDays(6);
        LocalDate fourthWeekStart = current.with(TemporalAdjusters.dayOfWeekInMonth(4, DayOfWeek.MONDAY));
        LocalDate fourthWeekEnd = fourthWeekStart.plusDays(6);
        LocalDate fifthWeekStart = current.with(TemporalAdjusters.dayOfWeekInMonth(5, DayOfWeek.MONDAY));

        Map<String, LocalDate> result = Maps.newConcurrentMap();
        if(fifthWeekStart.getMonthValue() == current.getMonthValue()){
            LocalDate fifthWeekEnd = fifthWeekStart.plusDays(6);
            result.put("FIFTH_WEEK_START", fifthWeekStart);
            result.put("FIFTH_WEEK_END", fifthWeekEnd);
        }

        result.put("FIRST_WEEK_START", firstWeekStart);
        result.put("FIRST_WEEK_END", firstWeekEnd);
        result.put("SECOND_WEEK_START", secondWeekStart);
        result.put("SECOND_WEEK_END", secondWeekEnd);
        result.put("THIRD_WEEK_START", thirdWeekStart);
        result.put("THIRD_WEEK_END", thirdWeekEnd);
        result.put("FOURTH_WEEK_START", fourthWeekStart);
        result.put("FOURTH_WEEK_END", fourthWeekEnd);

        return result;
    }


    /**
     * LocalDate转换为Date
     */
    public static Date LocalDateToDate(LocalDate localDate){
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDate.atStartOfDay(zoneId);
        Date date = Date.from(zdt.toInstant());

        return date;



    }

}
